package com.heima.media.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.dto.ResponseResult;
import com.heima.common.minio.MinIOService;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.media.dto.ArticleDto;
import com.heima.media.dto.ContentDto;
import com.heima.media.dto.ImageDto;
import com.heima.media.entity.WmChannel;
import com.heima.media.entity.WmNews;
import com.heima.media.entity.WmSensitive;
import com.heima.media.entity.WmUser;
import com.heima.media.feign.ArticleFeign;
import com.heima.media.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.aspectj.weaver.ast.Var;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class AuditServiceImpl implements IAuditService {

    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    @Lazy
    private IWmNewsService wmNewsService;
    @Autowired
    private MinIOService minIOService;
    @Autowired
    private ArticleFeign articleFeign;

    @Autowired
    private IWmUserService wmUserService;
    @Autowired
    private IWmChannelService channelService;
    @Override
    public void audit(Integer id) {
        WmNews wmNews = wmNewsService.getById(id);
        audit(wmNews);
    }
    @Override
    @Async
    public void audit(WmNews wmNews) {


//        使用DFA算法判断是否有敏感词
        boolean isPass = checkSensitive(wmNews);
        if(!isPass) return;
//         1、文本审核
        isPass = auditText(wmNews);
        if(!isPass) return;

//         2、图片审核
        isPass = auditImage(wmNews);
        if(!isPass) return;


//         4、修改自媒体文章的状态
//        0 草稿
//        1 提交（待审核）
//        2 审核失败
//        3 人工审核
//        4 人工审核通过
//        8 审核通过（待发布）
//        9 已发布
//        判断当前时间是否达到发布时间：  当前时间>=发布时间
        if(System.currentTimeMillis() >= wmNews.getPublishTime().getTime()){
            wmNews.setStatus(9);
//         发布app文章
            Long articleId = saveApArticle(wmNews);
            wmNews.setArticleId(articleId);
            wmNewsService.updateById(wmNews);
        }else{
            wmNews.setStatus(8);  //审核通过了，但是没有到发布时间
            wmNewsService.updateById(wmNews);
//            放自媒体文章id到延迟队列中
            RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque("article-queue");
            RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);

//            设置的时间-当前时间
           Long time = wmNews.getPublishTime().getTime() - System.currentTimeMillis();
            delayedQueue.offer(wmNews.getId(),time, TimeUnit.MILLISECONDS);// V 内容, long 延迟的时间, TimeUnit timeUnit
            log.info("延迟消息已存放成功");
        }
    }

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private IWmSensitiveService sensitiveService;

    private boolean checkSensitive(WmNews wmNews) {
        boolean isPass = true;

//        查询所有的敏感词
        List<WmSensitive> list = sensitiveService.list();
        List<String> wordList = new ArrayList<>();
        for (WmSensitive sensitive : list) {
            wordList.add(sensitive.getSensitives()) ;
        }
        //        初始化大Map
        SensitiveWordUtil.initMap(wordList);

        String text = wmNews.getTitle();
//        wmNews.getContent():[{"type":"text","value":"在今营的预判。"},
//        {"type":"image","value":"https://0e9.jpg"},
//        {"type":"text","value":"过了所有。烧\100%自主研发的\"纯中国芯\"，指日可待！"}]
        List<ContentDto> contentDtoList = JSON.parseArray(wmNews.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtoList) {
            if (contentDto.getType().equals("text")) {
                text+= contentDto.getValue();
            }
        }
        Map<String, Integer> matchWordsMap = SensitiveWordUtil.matchWords(text);
//        判断map中是否有内容，如果有代表：包含名词
        if(matchWordsMap.size()>0){
            wmNews.setStatus(2);
//            {小额贷款=1, 随机随贷=1, 无抵押=2}
            Set<String> strings = matchWordsMap.keySet();
            String join = String.join(",",strings);
            wmNews.setReason("敏感词审核失败，失败的原因是包含的敏感词有："+join );
            wmNewsService.updateById(wmNews);
            isPass=false;
        }
        return isPass;
    }


    public Long saveApArticle(WmNews wmNews) {

        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        articleDto.setId(null);

//        从wmUser中获取
        WmUser wmUser = wmUserService.getById(wmNews.getUserId());
        articleDto.setAuthorId(wmUser.getApUserId()); //文章作者id
        articleDto.setAuthorName(wmUser.getName());//文章作者名称
//        articleDto.setChannelId();
        WmChannel wmChannel = channelService.getById(wmNews.getChannelId());
        articleDto.setChannelName(wmChannel.getName());//频道名称
        articleDto.setLayout(wmNews.getType());
        articleDto.setFlag(0); //普通文章

//        wm_news:images
//[{"id":59,"url":"https://myth.oss-cn-beijing.aliyuncs.com/b7a35a40-dc8f-4625-a618-e4e8ece722e1.jpg"}]
//     ap_article:images
//        https://myth.oss-cn-beijing.aliyuncs.com/2d9ffa21-ebef-46dc-89f9-15735c6e90e9.jpg,https://myth.oss-cn-beijing.aliyuncs.com/7b8d20ec-7ccf-4d4c-aac2-603b769e2e89.jpg,https://myth.oss-cn-beijing.aliyuncs.com/258bdb6d-0e41-4bc8-95df-289dbeb5f263.jpg

        List<ImageDto> imageDtoList = JSON.parseArray(wmNews.getImages(), ImageDto.class);
        List<String> urlList = new ArrayList<>();
        for (ImageDto imageDto : imageDtoList) {
            urlList.add( imageDto.getUrl());
        }
        articleDto.setImages(String.join(",",urlList)); //注意格式


        ResponseResult<Long> responseResult = articleFeign.saveApArticle(articleDto);
        if(responseResult.getCode().equals(0)){
            return responseResult.getData();
        }else{
            throw new RuntimeException("远程调用失败");
        }
    }

    private boolean auditImage(WmNews wmNews) {
        boolean isPass = false;
        List<byte[]> imageList = new ArrayList<>();
//        图片包含两种：内容图片+封面图片

        List<String> urlList = new ArrayList<>();
//        获取内容中的图片地址
        List<ContentDto> contentDtoList = JSON.parseArray(wmNews.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtoList) {
            if (contentDto.getType().equals("image")) {
                urlList.add( contentDto.getValue());
            }
        }
//        还需要获取封面图片地址
       ;//[{"id":49,"url":"https://myth.oss-cn-beijing.aliyuncs.com/9d288d9f-0c23-4782-819a-1a5954d5e1ac.jpg"},{"id":50,"url":"https://myth.oss-cn-beijing.aliyuncs.com/543be389-c054-4f50-b145-2289df95d543.jpg"},{"id":51,"url":"https://myth.oss-cn-beijing.aliyuncs.com/66edcbf1-daeb-4ca8-97e4-64011e4cf64a.jpg"}]
        List<ImageDto> imageDtoList = JSON.parseArray(wmNews.getImages(), ImageDto.class);
        for (ImageDto imageDto : imageDtoList) {
            if(!urlList.contains(imageDto.getUrl())){
              urlList.add( imageDto.getUrl());
            }
        }
//        从minIO中下载图片
        try {
            for (String url : urlList) {
                InputStream inputStream = minIOService.download(url);
                byte[] bytes = IOUtils.toByteArray(inputStream);
                imageList.add(bytes);
            }
            Map map = greenImageScan.imageScan(imageList);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion){
                case "pass":{
                    isPass  = true;
                    break;
                }case "block":{
                    isPass  = false;
//                    修改自媒体文章的状态以及审核不通过的原因
//                    0 草稿
//                    1 提交（待审核）
//                    2 审核失败
//                    3 人工审核
//                    4 人工审核通过
//                    8 审核通过（待发布）
//                    9 已发布
                    wmNews.setStatus(2);
                    wmNews.setReason("阿里云图片审核失败，失败的原因是："+map.get("label"));
                    wmNewsService.updateById(wmNews);
                    break;
                }
                case "review":{
                    isPass  = false;
                    wmNews.setStatus(3);
                    wmNews.setReason("阿里云图片审核失败，失败的原因是："+map.get("label"));
                    wmNewsService.updateById(wmNews);
                    break;
                }
            }
        } catch (Exception e) {
            isPass  = false;
            e.printStackTrace();
        }
        return isPass;
    }

    private boolean auditText(WmNews wmNews) {
        boolean isPass = false;
//        文本：文章标题+文章内容
        String text = wmNews.getTitle();
//        wmNews.getContent():[{"type":"text","value":"在今营的预判。"},
//        {"type":"image","value":"https://0e9.jpg"},
//        {"type":"text","value":"过了所有。烧\100%自主研发的\"纯中国芯\"，指日可待！"}]
        List<ContentDto> contentDtoList = JSON.parseArray(wmNews.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtoList) {
            if (contentDto.getType().equals("text")) {
                text+= contentDto.getValue();
            }
        }

        try {
            Map map = greenTextScan.greenTextScan(text);
            //{suggestion=pass}
             //{suggestion=block, label=contraband}
             //{suggestion=review, label=contraband}
            String suggestion = (String) map.get("suggestion");
            switch (suggestion){
                case "pass":{
                    isPass  = true;
                    break;
                }case "block":{
                    isPass  = false;
//                    修改自媒体文章的状态以及审核不通过的原因
//                    0 草稿
//                    1 提交（待审核）
//                    2 审核失败
//                    3 人工审核
//                    4 人工审核通过
//                    8 审核通过（待发布）
//                    9 已发布
                    wmNews.setStatus(2);
                    wmNews.setReason("阿里云内容审核失败，失败的原因是："+map.get("label"));
                    wmNewsService.updateById(wmNews);
                    break;
                }
                case "review":{
                    isPass  = false;
                    wmNews.setStatus(3);
                    wmNews.setReason("阿里云内容审核失败，失败的原因是："+map.get("label"));
                    wmNewsService.updateById(wmNews);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return isPass;
    }
}
